/*
 * Copyright 2008 Federal Emergency Management Agency
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0 
 *    
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 *  
 */
package gov.fema.hazus.bdc.server.servlet;

import gov.fema.hazus.bdc.client.common.BuildingQuery;
import gov.fema.hazus.bdc.client.common.BuildingResults;
import gov.fema.hazus.bdc.client.services.BuildingService;
import gov.fema.hazus.bdc.client.services.ServerException;
import gov.fema.hazus.bdc.shared.entity.AEBMResults;
import gov.fema.hazus.bdc.shared.entity.Address;
import gov.fema.hazus.bdc.shared.entity.Bracing;
import gov.fema.hazus.bdc.shared.entity.Building;
import gov.fema.hazus.bdc.shared.entity.Capacity;
import gov.fema.hazus.bdc.shared.entity.Contact;
import gov.fema.hazus.bdc.shared.entity.EarthquakeBuildingDesign;
import gov.fema.hazus.bdc.shared.entity.EarthquakeHazard;
import gov.fema.hazus.bdc.shared.entity.EarthquakeSecondaryCharacteristics;
import gov.fema.hazus.bdc.shared.entity.Economy;
import gov.fema.hazus.bdc.shared.entity.FloodBasement;
import gov.fema.hazus.bdc.shared.entity.FloodBuildingDesign;
import gov.fema.hazus.bdc.shared.entity.FloodHazard;
import gov.fema.hazus.bdc.shared.entity.Location;
import gov.fema.hazus.bdc.shared.entity.ManufacturedHousing;
import gov.fema.hazus.bdc.shared.entity.Roof;
import gov.fema.hazus.bdc.shared.entity.WallsAndOpenings;
import gov.fema.hazus.bdc.shared.entity.WindBuildingDesign;
import gov.fema.hazus.bdc.shared.entity.WindHazard;

import java.util.ArrayList;
import java.util.Iterator;

import org.apache.log4j.Logger;

import com.google.appengine.api.datastore.FetchOptions;
import com.google.inject.Singleton;
import com.googlecode.objectify.OQuery;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;

@Singleton
public class BuildingServlet implements BuildingService {

	private static final long serialVersionUID = -8035494088209904890L;
	private final Logger logger = Logger.getLogger(BuildingServlet.class);

	private DAO dao = new DAO();
	
	public BuildingServlet()
    {
		
    }

	public void deleteBuildings(ArrayList<Building> buildings)
	{
		/*
		 * buildings in the list only have IDs, nothing else,
		 * so we need to delete by ID
		 */
		try {
			
			for (Iterator iterator = buildings.iterator(); iterator.hasNext();) {
				Building b = (Building) iterator.next();
				
				Long id = b.getId();
				
				Building building = dao.ofy().get(Building.class, id);
				

				AEBMResults aEBMResults = dao.ofy().get(AEBMResults.class, id);
				dao.ofy().delete(aEBMResults);

				Address address = dao.ofy().get(Address.class, id);
				dao.ofy().delete(address);

				Location location = dao.ofy().get(Location.class, id);
				dao.ofy().delete(location);

				Contact contact = dao.ofy().get(Contact.class, id);
				dao.ofy().delete(contact);

				Economy economy = dao.ofy().get(Economy.class, id);
				dao.ofy().delete(economy);

				Capacity capacity = dao.ofy().get(Capacity.class, id);
				dao.ofy().delete(capacity);

				Bracing bracing = dao.ofy().get(Bracing.class, id);
				dao.ofy().delete(bracing);

				EarthquakeHazard earthquakeHazard = dao.ofy().get(EarthquakeHazard.class, id);
				dao.ofy().delete(earthquakeHazard);

				EarthquakeBuildingDesign earthquakeBuildingDesign = dao.ofy().get(EarthquakeBuildingDesign.class, id);
				dao.ofy().delete(earthquakeBuildingDesign);

				EarthquakeSecondaryCharacteristics earthquakeSecondaryCharacteristics = dao.ofy().get(EarthquakeSecondaryCharacteristics.class, id);
				dao.ofy().delete(earthquakeSecondaryCharacteristics);

				FloodBasement floodBasement = dao.ofy().get(FloodBasement.class, id);
				dao.ofy().delete(floodBasement);

				FloodBuildingDesign floodBuildingDesign = dao.ofy().get(FloodBuildingDesign.class, id);
				dao.ofy().delete(floodBuildingDesign);

				FloodHazard floodHazard = dao.ofy().get(FloodHazard.class, id);
				dao.ofy().delete(floodHazard);

				ManufacturedHousing manufacturedHousing = dao.ofy().get(ManufacturedHousing.class, id);
				dao.ofy().delete(manufacturedHousing);

				Roof roof = dao.ofy().get(Roof.class, id);
				dao.ofy().delete(roof);

				WallsAndOpenings wallsAndOpenings = dao.ofy().get(WallsAndOpenings.class, id);
				dao.ofy().delete(wallsAndOpenings);

				WindBuildingDesign windBuildingDesign = dao.ofy().get(WindBuildingDesign.class, id);
				dao.ofy().delete(windBuildingDesign);

				WindHazard windHazard = dao.ofy().get(WindHazard.class, id);
				dao.ofy().delete(windHazard);

				
				// now delete the building
				dao.ofy().delete(building);
				
				
				}
			
			} catch (Exception e)
			{
				//TODO: warn user we could not delete 
			}
	}
	
	public BuildingResults find(BuildingQuery buildingQuery)
			throws ServerException {
		
		BuildingResults results = new BuildingResults();
		
		// get total building
		BuildingStatistics stats = new BuildingStatistics();
	    int totalBuildings = stats.getCount();
		results.setTotal(totalBuildings);
	    
		// looks like client prefers to get total from the query, not results
		buildingQuery.setTotal(totalBuildings);
		
		results.setBuildingQuery(buildingQuery);
		
		int offset = buildingQuery.getNext();
		int limit = buildingQuery.getMax();
		
		Objectify ofy = ObjectifyService.begin();
		OQuery<Building> q = ObjectifyService.createQuery(Building.class);
		q.sort("name"); // ascending sort on building name
		ArrayList<Building> buildings = (ArrayList<Building>) ofy.prepare(q).asList(FetchOptions.Builder.withLimit(limit).offset(offset));
		
		
		for (Iterator iterator = buildings.iterator(); iterator.hasNext();) {
			Building building = (Building) iterator.next();
			
			try {
				
				Address address = ofy.get(Address.class, building.getId());
				building.setAddress(address);
				
				
				//logger.debug(building.toString());
				
				// set up the children -- do we need to do this even for find()
				// -- should only be address and capacity for line display
				/*
				AEBMResults aebmResults = new AEBMResults();
				Address address = new Address();
				Location location = new Location();
				Contact contact = new Contact();
				Economy economy = new Economy();
				Capacity capacity = new Capacity();
				Bracing bracing = new Bracing();
				EarthquakeHazard earthquakeHazard = new EarthquakeHazard();
				EarthquakeBuildingDesign earthquakeBuildingDesign = new EarthquakeBuildingDesign();
				EarthquakeSecondaryCharacteristics earthquakeSecondaryCharacteristics = new EarthquakeSecondaryCharacteristics();
				FloodBasement floodBasement = new FloodBasement(); 
				FloodBuildingDesign floodBuildingDesign = new FloodBuildingDesign();
				FloodHazard floodHazard = new FloodHazard();
				ManufacturedHousing manufacturedHousing = new ManufacturedHousing();
				Roof roof = new Roof();
				WallsAndOpenings wallsAndOpenings = new WallsAndOpenings();
				WindBuildingDesign windBuildingDesign = new WindBuildingDesign();
				WindHazard windHazard = new WindHazard();
				*/
				
				//TODO: fetch the children via objectify
				
				// put the children in the building
				//building.setAebmResults(aebmResults);
				/*
				building.setAddress(address);
				building.setLocation(location);
				building.setContact(contact);
				building.setEconomy(economy);
				building.setCapacity(capacity);
				building.setBracing(bracing);
				building.setEarthquakeHazard(earthquakeHazard);
				building.setEarthquakeBuildingDesign(earthquakeBuildingDesign);
				building.setEarthquakeSecondaryCharacteristics(earthquakeSecondaryCharacteristics);
				building.setFloodBasement(floodBasement);
				building.setFloodBuildingDesign(floodBuildingDesign);
				building.setFloodHazard(floodHazard);
				building.setManufacturedHousing(manufacturedHousing);
				building.setRoof(roof);
				building.setWallsAndOpenings(wallsAndOpenings);
				building.setWindBuildingDesign(windBuildingDesign);
				building.setWindHazard(windHazard);
				*/
				
			} catch (Exception e) {
				logger.error(e);
			}
			
			
			
			
		}
		
		results.setBuildings(buildings);
		return results;
	}

	
	public Building getBuildingEarthquakeResults(Building building) throws ServerException {
		
		// get the basic building (name, etc)
		Objectify ofy = ObjectifyService.begin();
		OQuery<Building> q = ObjectifyService.createQuery(Building.class);
		q.filter("id == ", building.getId());
		Building fetched = (Building) ofy.prepare(q).asSingle();
		
		// use the building id to fetch the AEBM results, tuck them into the building
		OQuery<AEBMResults> q2 = ObjectifyService.createQuery(AEBMResults.class);
		q2.filter("id == ", building.getId());
		AEBMResults aebmResults = (AEBMResults) ofy.prepare(q2).asSingle();
		fetched.setAebmResults(aebmResults);
		
		// and the address too
		OQuery<Address> q3 = ObjectifyService.createQuery(Address.class);
		q3.filter("id == ", building.getId());
		Address address = (Address) ofy.prepare(q3).asSingle();
		fetched.setAddress(address);
		
		return fetched;
		
	}
	
	public Building getBuilding(Building building) throws ServerException {
		
		// TODO: check that building has ID (must have for this lookup)
		Objectify ofy = ObjectifyService.begin();
		OQuery<Building> q = ObjectifyService.createQuery(Building.class);
		q.sort("name"); // ascending sort on building name
		q.filter("id == ", building.getId());
		Building fetched = (Building) ofy.prepare(q).asSingle();
		
		/*
		 * Building coming from datastore may or may not have a user.
		 * 
		 * If the building has a user (not empty), check if it is the 
		 * same as the incoming. If it is, no problem. If it is not, 
		 * mark the building as read only
		 */
		
		/*
	        if( !loggedInUser.getUsername().equalsIgnoreCase(userWithBuildingLock ))
	        {
	        	GWT.log("logged in user name != user with building lock", null);
	        	userLocked.setHTML("<b>" + userWithBuildingLock + "</b> " + constants.editingUser());
	        }
	        else
	        {
	        	GWT.log("logged in user name == user with building lock", null);
	        	userLocked.setHTML(constants.unlockMessage());
	        }
		 */
		logger.debug("BUILDING USERNAME=" + building.getUserName());
		logger.debug("FETCHED USERNAME=" + fetched.getUserName());
		if( !fetched.getUserName().equals(""))
		{
			if( !fetched.getUserName().equalsIgnoreCase( building.getUserName() ))
			{
				fetched.setMode(Building.READ_ONLY);
			} else {
				// user names match, so the building is editable
				fetched.setUserName(building.getUserName());
				logger.debug("CHANGE FETCHED MODE TO EDITABLE");
				fetched.setMode(Building.EDITABLE);
			}
		} else {
			logger.debug("setting building username to " + building.getUserName());
			fetched.setUserName(building.getUserName());
			
		}
		dao.ofy().put(fetched);
		logger.debug("BUILDING EDIT MODE=" + fetched.getMode());
		
		OQuery<AEBMResults> queryAEBMResults = ObjectifyService.createQuery(AEBMResults.class);
		queryAEBMResults.filter("id == ", fetched.getId());
		AEBMResults aEBMResults = (AEBMResults) ofy.prepare(queryAEBMResults).asSingle();
		fetched.setAebmResults(aEBMResults);

		OQuery<Address> queryAddress = ObjectifyService.createQuery(Address.class);
		queryAddress.filter("id == ", fetched.getId());
		Address address = (Address) ofy.prepare(queryAddress).asSingle();
		fetched.setAddress(address);

		OQuery<Location> queryLocation = ObjectifyService.createQuery(Location.class);
		queryLocation.filter("id == ", fetched.getId());
		Location location = (Location) ofy.prepare(queryLocation).asSingle();
		fetched.setLocation(location);

		OQuery<Contact> queryContact = ObjectifyService.createQuery(Contact.class);
		queryContact.filter("id == ", fetched.getId());
		Contact contact = (Contact) ofy.prepare(queryContact).asSingle();
		fetched.setContact(contact);

		OQuery<Economy> queryEconomy = ObjectifyService.createQuery(Economy.class);
		queryEconomy.filter("id == ", fetched.getId());
		Economy economy = (Economy) ofy.prepare(queryEconomy).asSingle();
		fetched.setEconomy(economy);

		OQuery<Capacity> queryCapacity = ObjectifyService.createQuery(Capacity.class);
		queryCapacity.filter("id == ", fetched.getId());
		Capacity capacity = (Capacity) ofy.prepare(queryCapacity).asSingle();
		fetched.setCapacity(capacity);

		OQuery<Bracing> queryBracing = ObjectifyService.createQuery(Bracing.class);
		queryBracing.filter("id == ", fetched.getId());
		Bracing bracing = (Bracing) ofy.prepare(queryBracing).asSingle();
		fetched.setBracing(bracing);
		
		OQuery<EarthquakeHazard> queryEarthquakeHazard = ObjectifyService.createQuery(EarthquakeHazard.class);
		queryEarthquakeHazard.filter("id == ", fetched.getId());
		EarthquakeHazard earthquakeHazard = (EarthquakeHazard) ofy.prepare(queryEarthquakeHazard).asSingle();
		fetched.setEarthquakeHazard(earthquakeHazard);

		OQuery<EarthquakeBuildingDesign> queryEarthquakeBuildingDesign = ObjectifyService.createQuery(EarthquakeBuildingDesign.class);
		queryEarthquakeBuildingDesign.filter("id == ", fetched.getId());
		EarthquakeBuildingDesign earthquakeBuildingDesign = (EarthquakeBuildingDesign) ofy.prepare(queryEarthquakeBuildingDesign).asSingle();
		fetched.setEarthquakeBuildingDesign(earthquakeBuildingDesign);

		OQuery<EarthquakeSecondaryCharacteristics> queryEarthquakeSecondaryCharacteristics = ObjectifyService.createQuery(EarthquakeSecondaryCharacteristics.class);
		queryEarthquakeSecondaryCharacteristics.filter("id == ", fetched.getId());
		EarthquakeSecondaryCharacteristics earthquakeSecondaryCharacteristics = (EarthquakeSecondaryCharacteristics) ofy.prepare(queryEarthquakeSecondaryCharacteristics).asSingle();
		fetched.setEarthquakeSecondaryCharacteristics(earthquakeSecondaryCharacteristics);

		OQuery<FloodBasement> queryFloodBasement = ObjectifyService.createQuery(FloodBasement.class);
		queryFloodBasement.filter("id == ", fetched.getId());
		FloodBasement floodBasement = (FloodBasement) ofy.prepare(queryFloodBasement).asSingle();
		fetched.setFloodBasement(floodBasement);

		OQuery<FloodBuildingDesign> queryFloodBuildingDesign = ObjectifyService.createQuery(FloodBuildingDesign.class);
		queryFloodBuildingDesign.filter("id == ", fetched.getId());
		FloodBuildingDesign floodBuildingDesign = (FloodBuildingDesign) ofy.prepare(queryFloodBuildingDesign).asSingle();
		fetched.setFloodBuildingDesign(floodBuildingDesign);

		OQuery<FloodHazard> queryFloodHazard = ObjectifyService.createQuery(FloodHazard.class);
		queryFloodHazard.filter("id == ", fetched.getId());
		FloodHazard floodHazard = (FloodHazard) ofy.prepare(queryFloodHazard).asSingle();
		fetched.setFloodHazard(floodHazard);

		OQuery<ManufacturedHousing> queryManufacturedHousing = ObjectifyService.createQuery(ManufacturedHousing.class);
		queryManufacturedHousing.filter("id == ", fetched.getId());
		ManufacturedHousing manufacturedHousing = (ManufacturedHousing) ofy.prepare(queryManufacturedHousing).asSingle();
		fetched.setManufacturedHousing(manufacturedHousing);

		OQuery<Roof> queryRoof = ObjectifyService.createQuery(Roof.class);
		queryRoof.filter("id == ", fetched.getId());
		Roof roof = (Roof) ofy.prepare(queryRoof).asSingle();
		fetched.setRoof(roof);

		OQuery<WallsAndOpenings> queryWallsAndOpenings = ObjectifyService.createQuery(WallsAndOpenings.class);
		queryWallsAndOpenings.filter("id == ", fetched.getId());
		WallsAndOpenings wallsAndOpenings = (WallsAndOpenings) ofy.prepare(queryWallsAndOpenings).asSingle();
		fetched.setWallsAndOpenings(wallsAndOpenings);

		OQuery<WindBuildingDesign> queryWindBuildingDesign = ObjectifyService.createQuery(WindBuildingDesign.class);
		queryWindBuildingDesign.filter("id == ", fetched.getId());
		WindBuildingDesign windBuildingDesign = (WindBuildingDesign) ofy.prepare(queryWindBuildingDesign).asSingle();
		fetched.setWindBuildingDesign(windBuildingDesign);

		OQuery<WindHazard> queryWindHazard = ObjectifyService.createQuery(WindHazard.class);
		queryWindHazard.filter("id == ", fetched.getId());
		WindHazard windHazard = (WindHazard) ofy.prepare(queryWindHazard).asSingle();
		fetched.setWindHazard(windHazard);
		
		
		return fetched;
		
	}

	public ArrayList<Location> getBuildingLocations() throws ServerException {

		// fetch all of the locations
		Objectify ofy = ObjectifyService.begin();
		OQuery<Location> q = ObjectifyService.createQuery(Location.class);
		//ArrayList<OKey<Building>> buildings = (ArrayList<OKey<Building>>) ofy.prepareKeysOnly(q).asList(FetchOptions.Builder.withLimit(Integer.MAX_VALUE).offset(0));
		ArrayList<Location> locations = (ArrayList<Location>) ofy.prepare(q).asList();
		return locations;
		
	}

	public BuildingResults getBuildings() throws ServerException {

		return null;
		
	}
	
	
	public void releaseBuilding(Building building) throws ServerException {
		
		Objectify ofy = ObjectifyService.begin();
		OQuery<Building> q = ObjectifyService.createQuery(Building.class);
		q.filter("id == ", building.getId());
		Building fetched = (Building) ofy.prepare(q).asSingle();
		fetched.setUserName(""); // releases the building for editing by other users
		dao.ofy().put(fetched);
		
	}

	public Building save(Building building) throws ServerException {
		
		/*
		 * TODO: check if we are saving a new building
		 */
		if( building.getId() == null)
		{
			saveNewBuilding(building);
		}
		
		validateBuilding(building);
		
		/*
		 * TODO: set up search terms for this building
		 */
		ArrayList<String> terms = new ArrayList<String>();
		String name = building.getName();
		logger.debug(name);
		name = name.replaceAll("[^a-zA-Z 0-9]", " ");
		name = name.replaceAll("\\s+ ", " ");
		logger.debug(name);
		name = name.toUpperCase();
		logger.debug(name);
		String[] words = name.split(" ");	
		for (int i = 0; i < words.length; i++) {
			logger.debug(words[i]);
			String term = words[i];
			// add term to terms
			terms.add(term);
		}
		building.setTerms(terms);
		
		/*
		 * TODO: save each component of the building.
		 * We are assuming the client did all of the validation work.
		 */
		// set the mode
		//building.setMode(Building.EDITABLE);
		//building.setUserName("");
		
		dao.ofy().put(building);
		
		
		/*
		 * With the way we have implemented Objectify, we need to 
		 * extract all of the child objects from the building and save
		 * them individually
		 */
		building.getAddress().setId(building.getId());
		dao.ofy().put(building.getAddress());
		
		// never gets edited by user, so does not need persistence here
		building.getAebmResults().setId(building.getId());
		dao.ofy().put(building.getAebmResults());
		
		building.getBracing().setId(building.getId());
		dao.ofy().put(building.getBracing());
		
		building.getCapacity().setId(building.getId());
		dao.ofy().put(building.getCapacity());
		
		building.getContact().setId(building.getId());
		dao.ofy().put(building.getContact());
		
		building.getEarthquakeBuildingDesign().setId(building.getId());
		dao.ofy().put(building.getEarthquakeBuildingDesign());
		
		building.getEarthquakeHazard().setId(building.getId());
		dao.ofy().put(building.getEarthquakeHazard());
		
		building.getEarthquakeSecondaryCharacteristics().setId(building.getId());
		dao.ofy().put(building.getEarthquakeSecondaryCharacteristics());
		
		building.getEconomy().setId(building.getId());
		dao.ofy().put(building.getEconomy());
		
		building.getFloodBasement().setId(building.getId());
		dao.ofy().put(building.getFloodBasement());
		
		building.getFloodBuildingDesign().setId(building.getId());
		dao.ofy().put(building.getFloodBuildingDesign());
		
		building.getFloodHazard().setId(building.getId());
		dao.ofy().put(building.getFloodHazard());
		
		building.getLocation().setId(building.getId());
		dao.ofy().put(building.getLocation());
		
		building.getManufacturedHousing().setId(building.getId());
		dao.ofy().put(building.getManufacturedHousing());
		
		building.getRoof().setId(building.getId());
		dao.ofy().put(building.getRoof());
		
		building.getWallsAndOpenings().setId(building.getId());
		dao.ofy().put(building.getWallsAndOpenings());
		
		building.getWindBuildingDesign().setId(building.getId());
		dao.ofy().put(building.getWindBuildingDesign());
		
		building.getWindHazard().setId(building.getId());
		dao.ofy().put(building.getWindHazard());
		
		return building;
	}

	public BuildingResults search(BuildingQuery buildingQuery) throws ServerException {

		BuildingResults results = new BuildingResults();
		
		// get total building
		BuildingStatistics stats = new BuildingStatistics();
	    int totalBuildings = stats.getSearchCount(buildingQuery);
		results.setTotal(totalBuildings);
	    
		// looks like client prefers to get total from the query, not results
		buildingQuery.setTotal(totalBuildings);
		
		results.setBuildingQuery(buildingQuery);
		
		int offset = buildingQuery.getNext();
		int limit = buildingQuery.getMax();
		
		Objectify ofy = ObjectifyService.begin();
		OQuery<Building> q = ObjectifyService.createQuery(Building.class);
		q.sort("name"); // ascending sort on building name
		q.filter("terms == ", buildingQuery.getSearchTerm().toUpperCase());
		ArrayList<Building> buildings = (ArrayList<Building>) ofy.prepare(q).asList(FetchOptions.Builder.withLimit(limit).offset(offset));
		
		
		for (Iterator iterator = buildings.iterator(); iterator.hasNext();) {
			Building building = (Building) iterator.next();
			
			try {
				
				Address address = ofy.get(Address.class, building.getId());
				building.setAddress(address);
				
				//logger.debug(building.toString());
				
				// set up the children -- do we need to do this even for find()
				// -- should only be address and capacity for line display
				/*
				AEBMResults aebmResults = new AEBMResults();
				Address address = new Address();
				Location location = new Location();
				Contact contact = new Contact();
				Economy economy = new Economy();
				Capacity capacity = new Capacity();
				Bracing bracing = new Bracing();
				EarthquakeHazard earthquakeHazard = new EarthquakeHazard();
				EarthquakeBuildingDesign earthquakeBuildingDesign = new EarthquakeBuildingDesign();
				EarthquakeSecondaryCharacteristics earthquakeSecondaryCharacteristics = new EarthquakeSecondaryCharacteristics();
				FloodBasement floodBasement = new FloodBasement(); 
				FloodBuildingDesign floodBuildingDesign = new FloodBuildingDesign();
				FloodHazard floodHazard = new FloodHazard();
				ManufacturedHousing manufacturedHousing = new ManufacturedHousing();
				Roof roof = new Roof();
				WallsAndOpenings wallsAndOpenings = new WallsAndOpenings();
				WindBuildingDesign windBuildingDesign = new WindBuildingDesign();
				WindHazard windHazard = new WindHazard();
				*/
				
				//TODO: fetch the children via objectify
				
				// put the children in the building
				//building.setAebmResults(aebmResults);
				/*
				building.setAddress(address);
				building.setLocation(location);
				building.setContact(contact);
				building.setEconomy(economy);
				building.setCapacity(capacity);
				building.setBracing(bracing);
				building.setEarthquakeHazard(earthquakeHazard);
				building.setEarthquakeBuildingDesign(earthquakeBuildingDesign);
				building.setEarthquakeSecondaryCharacteristics(earthquakeSecondaryCharacteristics);
				building.setFloodBasement(floodBasement);
				building.setFloodBuildingDesign(floodBuildingDesign);
				building.setFloodHazard(floodHazard);
				building.setManufacturedHousing(manufacturedHousing);
				building.setRoof(roof);
				building.setWallsAndOpenings(wallsAndOpenings);
				building.setWindBuildingDesign(windBuildingDesign);
				building.setWindHazard(windHazard);
				*/
				
			} catch (Exception e) {
				logger.error(e);
			}
			
			
			
			
		}
		
		results.setBuildings(buildings);
		return results;
		
		/*
    	this.pm = pmf.getPersistenceManager();
    	pm.currentTransaction().begin();
    	
    	// convert to upper case
    	String searchTerm = buildingQuery.getSearchTerm().toUpperCase();
    	
    	// set up the results
    	ArrayList<Building> buildings = new ArrayList<Building>();
    	BuildingResults results = new BuildingResults();
    	results.setBuildingQuery(buildingQuery);

    	int indexInt = buildingQuery.getNext();
		int offsetInt = buildingQuery.getMax();
		
		String begin = Integer.toString(indexInt);
		String end = Integer.toString(indexInt + offsetInt);
		
    	String where = " WHERE terms == '"+searchTerm+"'";
    	String order = " ORDER BY name ASC";
		String range = " RANGE " + begin + "," + end;
		String gql = "SELECT FROM gov.fema.hazus.bdc.server.dto.DTO_Building" + where + order + range;
		
		List<DTO_Building> dtoBuildings = (List<DTO_Building>) pm.newQuery(gql).execute();
	    for (Iterator iterator = dtoBuildings.iterator(); iterator.hasNext();) {
			DTO_Building dtoBuilding = (DTO_Building) iterator.next();
			
			Building building = new Building();
			

			building.setId(dtoBuilding.getId());
			logger.debug("dto building id=" + building.getId());
			logger.debug("dto building name=" + dtoBuilding.getName());
			logger.debug("dto building username=" + dtoBuilding.getUserName());
			
			building.setName(dtoBuilding.getName());
			building.setUserName(dtoBuilding.getUserName());
			
			buildings.add(building);
		}

		pm.currentTransaction().commit();
		
		// this is just the size of the range search, not all the matching search terms
		int totalCountForSearchTerm = getTotalCount(searchTerm);
		logger.debug("setting total search count to:" + totalCountForSearchTerm);
		results.setTotal(totalCountForSearchTerm);
		
	    results.setBuildings(buildings);
	    return results;
		*/
		
	}
	
	private Building saveNewBuilding(Building building) throws ServerException
	{
		logger.debug("saving new building");
		
		validateBuilding(building);
		
		// save the building to get an ID
		dao.ofy().put(building);
		
		
		return building;
	}
	

	private void validateBuilding(Building building) throws ServerException {
		/*
		 * If we don't have a name or number, then throw exception
		 */
		if( building.getName() == null 
				|| building.getName().equalsIgnoreCase("")
				|| building.getName().matches("^\\s+$"))
		{
			throw new ServerException("A building name is required");
		}
		
		if( building.getNumber() == null 
				|| building.getNumber().equalsIgnoreCase("")
				|| building.getNumber().matches("^\\s+$"))
		{
			throw new ServerException("A building number is required");
		}
	}
	

    
}
